/**
 * @author t.murdock
 *
 * @class Ext.ux.form.HexField
 * @extends Ext.form.TextField
 *
 * Will only allow Hex values
 */

Ext.namespace("Ext.ux.form");

Ext.ux.form.HexField = Ext.extend(Ext.form.TextField, {
    initEvents: function() {
        Ext.ux.form.HexField.superclass.initEvents.call(this);

        var keyPress = function(e) {
            var k = e.getKey();

            if (!Ext.isIE && (e.isSpecialKey() || k == e.BACKSPACE || k == e.DELETE)) {
                return;
            }

            // allowed text characters
            var allowed = '0123456789abcdefABCDEF';

            // get selected text length
            var selection = new Ext.ux.form.HexField.Selection(document.getElementById(this.id));
            var s = selection.create();
            var selLength = s.end - s.start;

            // get text character keyed in
            var c = e.getCharCode();
            var c = String.fromCharCode(c);
            var value = c + this.getValue();

            if (allowed.indexOf(c) === -1 || (value.length > 6 && selLength === 0)) {
                e.stopEvent();
            }
        };
        this.el.on("keypress", keyPress, this);
    }

    ,
    validateValue: function(value) {
        if (!Ext.ux.form.HexField.superclass.validateValue.call(this, value)) {
            return false;
        }
        if (!/^[0-9a-fA-F]{6}$/.test(value)) {
            return false;
        }
        return true;
    }
});
Ext.reg('hexfield', Ext.ux.form.HexField);

Ext.ux.form.HexField.Selection = function(textareaElement) {
    this.element = textareaElement;
};

Ext.ux.form.HexField.Selection.prototype.create = function() {
    if (document.selection != null && this.element.selectionStart == null) {
        return this._ieGetSelection();
    } else {
        return this._mozillaGetSelection();
    }
}

Ext.ux.form.HexField.Selection.prototype._mozillaGetSelection = function() {
    return {
        start: this.element.selectionStart,
        end: this.element.selectionEnd
    };
}

Ext.ux.form.HexField.Selection.prototype._ieGetSelection = function() {
    this.element.focus();

    var range = document.selection.createRange();
    var bookmark = range.getBookmark();

    var contents = this.element.value;
    var originalContents = contents;
    var marker = this._createSelectionMarker();
    while (contents.indexOf(marker) != -1) {
        marker = this._createSelectionMarker();
    }
    var parent = range.parentElement();
    if (parent == null || parent.type != "text") {
        return {
            start: 0,
            end: 0
        };
    }
    range.text = marker + range.text + marker;
    contents = this.element.value;

    var result = {};
    result.start = contents.indexOf(marker);
    contents = contents.replace(marker, "");
    result.end = contents.indexOf(marker);

    this.element.value = originalContents;
    range.moveToBookmark(bookmark);
    range.select();

    return result;
}

Ext.ux.form.HexField.Selection.prototype._createSelectionMarker = function() {
    return "##SELECTION_MARKER_" + Math.random() + "##";
}
/**
 * Original code is taken from vtswingkid's (Ext JS Forum member) form.ux.ColorPickerField
 * URL: http://extjs.com/forum/showthread.php?t=47450
 * 
 * Additional modifications have been made to the Ext.ux.ColorDialog by Todd Murdock.
 */

/**
 * @class Ext.ux.ColorPicker
 * @extends Ext.BoxComponent
 */
Ext.namespace("Ext.ux", "Ext.ux.menu");

Ext.ux.ColorPicker = Ext.extend(Ext.BoxComponent, {
    initColor: 'ffffff',

    showWebSafeColorbox: false,
    showInverseColorbox: false,
    showColorbox: true,
    showOriginalColorbox: true,

    initComponent: function() {
        this.applyDefaultsCP();
        Ext.ux.ColorPicker.superclass.initComponent.apply(this, arguments);
        this.addEvents({
            'select': true,
            'update': true,
            'cancel': true
        });
    },

    onRender: function() {
        Ext.ux.ColorPicker.superclass.onRender.apply(this, arguments);
        // check if container, self-container or renderTo exists
        this.body = this.body || (this.container || (this.renderTo || Ext.DomHelper.append(Ext.getBody(), {},
        true)));
        if (!this.el) {
            this.el = this.body;
            if (this.cls) {
                Ext.get(this.el).addClass(this.cls);
            }
        }
        // render this component
        this.renderComponent();
    },

    applyDefaultsCP: function() {
        Ext.apply(this, {
            'cls': 'x-cp-mainpanel',
            'resizable': this.resizable || false,
            'HSV': {
                h: 0,
                s: 0,
                v: 0
            },
            updateMode: null
        });
    },

    renderComponent: function() {
        // create RGB Slider
        Ext.DomHelper.append(this.body, {
            'id': this.cpGetId('rgb'),
            'cls': 'x-cp-rgbpicker'
        });

        // Create HUE Slider
        Ext.DomHelper.append(this.body, {
            'id': this.cpGetId('hue'),
            'cls': 'x-cp-huepicker'
        });
        // Initialize HUE Picker DD
        this.huePicker = Ext.DomHelper.append(this.body, {
            'cls': 'x-cp-hueslider'
        });
        this.hueDD = new Ext.dd.DD(this.huePicker, 'huePicker');
        this.hueDD.constrainTo(this.cpGetId('hue'), {
            'top': -7,
            'right': -3,
            'bottom': -7,
            'left': -3
        });
        this.hueDD.onDrag = this.moveHuePicker.createDelegate(this);

        // initialize onclick on the rgb picker
        Ext.get(this.cpGetId('hue')).on('mousedown', this.clickHUEPicker.createDelegate(this));

        // initialize start position
        Ext.get(this.huePicker).moveTo(Ext.get(this.cpGetId('hue')).getLeft() - 3, Ext.get(this.cpGetId('hue')).getTop() - 7);

        // Initialize RGB Picker DD
        this.rgbPicker = Ext.DomHelper.append(this.body, {
            'cls': 'x-cp-rgbslider'
        });
        this.rgbDD = new Ext.dd.DD(this.rgbPicker, 'rgbPicker');
        this.rgbDD.constrainTo(this.cpGetId('rgb'), -7);
        this.rgbDD.onDrag = this.moveRGBPicker.createDelegate(this);

        // initialize onclick on the rgb picker
        Ext.get(this.cpGetId('rgb')).on('mousedown', this.clickRGBPicker.createDelegate(this));
        // initialize start position
        Ext.get(this.rgbPicker).moveTo(Ext.get(this.cpGetId('rgb')).getLeft() - 7, Ext.get(this.cpGetId('rgb')).getTop() - 7);

        // Create color divs and Form elements
        this.formPanel = new Ext.form.FormPanel({
            border: false,
            renderTo: Ext.DomHelper.append(this.body, {
                id: this.cpGetId('fCont'),
                cls: 'x-cp-formcontainer'
            },
            true),
            frame: false,
            labelAlign: 'left',
            labelWidth: 10,
            forceLayout: true,
            items: [{ // Color box
                border: false,
                layout: 'form',
                id: this.cpGetId('cCont')
            },
            {
                bodyStyle: 'padding-top:10px;',
                border: false,
                layout: 'column',
                items: [{ // RGB fields
                    border: false,
                    columnWidth: .5,
                    layout: 'form',
                    defaultType: 'numberfield',
                    defaults: {
                        width: 30,
                        value: 0,
                        minValue: 0,
                        maxValue: 255,
                        allowBlank: false,
                        labelSeparator: '',
                        enableKeyEvents: true
                    },
                    items: [{
                        fieldLabel: 'R',
                        id: this.cpGetId('iRed')
                    },
                    {
                        fieldLabel: 'G',
                        id: this.cpGetId('iGreen')
                    },
                    {
                        fieldLabel: 'B',
                        id: this.cpGetId('iBlue')
                    }]
                },
                { // HSV Fields
                    border: false,
                    columnWidth: .5,
                    layout: 'form',
                    defaultType: 'numberfield',
                    defaults: {
                        width: 30,
                        value: 0,
                        minValue: 0,
                        maxValue: 255,
                        allowBlank: false,
                        labelSeparator: '',
                        enableKeyEvents: true
                    },
                    items: [{
                        fieldLabel: 'H',
                        maxValue: 360,
                        id: this.cpGetId('iHue')
                    },
                    {
                        fieldLabel: 'S',
                        id: this.cpGetId('iSat')
                    },
                    {
                        fieldLabel: 'V',
                        id: this.cpGetId('iVal')
                    }]
                },
                { // HEX field panel
                    border: false,
                    layout: 'form',
                    labelAlign: 'left',
                    items: [{
                        width: 88,
                        value: '000000',
                        labelSeparator: '',
                        allowBlank: false,
                        fieldLabel: '#',
                        id: this.cpGetId('iHexa'),
                        xtype: 'hexfield',
                        enableKeyEvents: true
                        // regex: /^[0-9a-fA-F]{6}$/
                    }]
                }]
            }]
        });
        Ext.getCmp(this.cpGetId('iRed')).on('keyup', this.updateFromIRGB.createDelegate(this), {
            buffer: 750
        });
        Ext.getCmp(this.cpGetId('iGreen')).on('keyup', this.updateFromIRGB.createDelegate(this), {
            buffer: 750
        });
        Ext.getCmp(this.cpGetId('iBlue')).on('keyup', this.updateFromIRGB.createDelegate(this), {
            buffer: 750
        });
        Ext.getCmp(this.cpGetId('iHue')).on('keyup', this.updateFromIHSV.createDelegate(this), {
            buffer: 750
        });
        Ext.getCmp(this.cpGetId('iSat')).on('keyup', this.updateFromIHSV.createDelegate(this), {
            buffer: 750
        });
        Ext.getCmp(this.cpGetId('iVal')).on('keyup', this.updateFromIHSV.createDelegate(this), {
            buffer: 750
        });
        Ext.getCmp(this.cpGetId('iHexa')).on('keyup', this.updateFromIHexa.createDelegate(this), {
            buffer: 750
        });

        var cContBody = Ext.getCmp(this.cpGetId('cCont')).body;
        var boxCount = 0;

        cContBody.setStyle({
            border: '1px solid #B5B8C8',
            margin: '0 0 0 13px',
            width: '88px'
        });

        if (this.showWebSafCoorbox === true) { // show web save color box
            boxCount++;
            Ext.DomHelper.append(cContBody, {
                'cls': 'x-cp-colorbox',
                'id': this.cpGetId('cWebSafe')
            },
            true).update('Websafe');
            Ext.get(this.cpGetId('cWebSafe')).on('click', this.updateFromBox.createDelegate(this));
        }
        if (this.showInverseColorbox === true) { // show inverse color box
            boxCount++;
            Ext.DomHelper.append(cContBody, {
                'cls': 'x-cp-colorbox',
                'id': this.cpGetId('cInverse')
            },
            true).update('Inverse');
            Ext.get(this.cpGetId('cInverse')).on('click', this.updateFromBox.createDelegate(this));
        }
        if (this.showColorbox === true) { // show color box
            boxCount++;
            Ext.DomHelper.append(cContBody, {
                'cls': 'x-cp-colorbox',
                'id': this.cpGetId('cColor')
            },
            true); //.update( 'Pick Color' );
            Ext.get(this.cpGetId('cColor')).on('click', this.selectColor.createDelegate(this));
        }
        if (this.showOriginalColorbox === true) { // show original color box
            boxCount++;
            Ext.DomHelper.append(cContBody, {
                'cls': 'x-cp-colorbox',
                'id': this.cpGetId('cOriginal')
            },
            true);
            Ext.get(this.cpGetId('cOriginal')).on('click', this.resetColor.createDelegate(this));
        }

        // set the box height depending on the box count
        Ext.util.CSS.updateRule('.x-cp-colorbox', 'height', parseInt(69 / boxCount) + 'px');

        Ext.DomHelper.append(this.body, {
            'tag': 'br',
            'cls': 'x-cp-clearfloat'
        });
    },
    cpGetId: function(postfix) {
        return this.getId() + '__' + (postfix || 'cp');
    },

    updateRGBPosition: function(x, y) {
        this.updateMode = 'click';
        x = x < 0 ? 0 : x;
        x = x > 181 ? 181 : x;
        y = y < 0 ? 0 : y;
        y = y > 181 ? 181 : y;
        this.HSV.s = this.getSaturation(x);
        this.HSV.v = this.getValue(y);
        Ext.get(this.rgbPicker).moveTo(Ext.get(this.cpGetId('rgb')).getLeft() + x - 7, Ext.get(this.cpGetId('rgb')).getTop() + y - 7, (this.animateMove || true));
        this.updateColor();
    },

    updateHUEPosition: function(y) {
        this.updateMode = 'click';
        y = y < 1 ? 1 : y;
        y = y > 181 ? 181 : y;
        this.HSV.h = Math.round(360 / 181 * (181 - y));
        Ext.get(this.huePicker).moveTo(Ext.get(this.huePicker).getLeft(), Ext.get(this.cpGetId('hue')).getTop() + y - 7, (this.animateMove || true));
        this.updateRGBPicker(this.HSV.h);
        this.updateColor();
    },

    clickRGBPicker: function(event, element) {
        this.updateRGBPosition(event.xy[0] - Ext.get(this.cpGetId('rgb')).getLeft(), event.xy[1] - Ext.get(this.cpGetId('rgb')).getTop());
    },

    clickHUEPicker: function(event, element) {
        this.updateHUEPosition(event.xy[1] - Ext.get(this.cpGetId('hue')).getTop());
    },

    moveRGBPicker: function(event) {
        this.rgbDD.constrainTo(this.cpGetId('rgb'), -7);
        this.updateRGBPosition(Ext.get(this.rgbPicker).getLeft() - Ext.get(this.cpGetId('rgb')).getLeft() + 7, Ext.get(this.rgbPicker).getTop() - Ext.get(this.cpGetId('rgb')).getTop() + 7);
    },

    moveHuePicker: function(event) {
        this.hueDD.constrainTo(this.cpGetId('hue'), {
            'top': -7,
            'right': -3,
            'bottom': -7,
            'left': -3
        });
        this.updateHUEPosition(Ext.get(this.huePicker).getTop() - Ext.get(this.cpGetId('hue')).getTop() + 7);
    },
    updateRGBPicker: function(newValue) {
        this.updateMode = 'click';
        Ext.get(this.cpGetId('rgb')).setStyle({
            'background-color': '#' + this.rgbToHex(this.hsvToRgb(newValue, 1, 1))
        });
        this.updateColor();
    },

    updateColor: function() {
        var rgb = this.hsvToRgb(this.HSV.h, this.HSV.s, this.HSV.v);
        var websafe = this.websafe(rgb);
        var invert = this.invert(rgb);
        var wsInvert = this.invert(websafe);
        if (this.updateMode !== 'hexa') {
            Ext.getCmp(this.cpGetId('iHexa')).setValue(this.rgbToHex(rgb));
        }
        if (this.updateMode !== 'rgb') {
            Ext.getCmp(this.cpGetId('iRed')).setValue(rgb[0]);
            Ext.getCmp(this.cpGetId('iGreen')).setValue(rgb[1]);
            Ext.getCmp(this.cpGetId('iBlue')).setValue(rgb[2]);
        }
        if (this.updateMode !== 'hsv') {
            Ext.getCmp(this.cpGetId('iHue')).setValue(Math.round(this.HSV.h));
            Ext.getCmp(this.cpGetId('iSat')).setValue(Math.round(this.HSV.s * 100));
            Ext.getCmp(this.cpGetId('iVal')).setValue(Math.round(this.HSV.v * 100));
        }

        if (this.showColorbox === true) {
            Ext.get(this.cpGetId('cColor')).setStyle({
                'background': '#' + this.rgbToHex(rgb),
                'color': '#' + this.rgbToHex(invert)
            });
            //Ext.getDom( this.cpGetId( 'cColor' ) ).title = '#'+this.rgbToHex( rgb );
        }

        if (this.showInverseColorbox === true) {
            Ext.get(this.cpGetId('cInverse')).setStyle({
                'background': '#' + this.rgbToHex(invert),
                'color': '#' + this.rgbToHex(rgb)
            });
            //Ext.getDom( this.cpGetId( 'cInverse' ) ).title = '#'+this.rgbToHex( invert );
        }
        if (this.showWebSafeColorbox === true) {
            Ext.get(this.cpGetId('cWebSafe')).setStyle({
                'background': '#' + this.rgbToHex(websafe),
                'color': '#' + this.rgbToHex(wsInvert)
            });
            //Ext.getDom( this.cpGetId( 'cWebSafe' ) ).title = '#'+this.rgbToHex( websafe );
        }

        if (this.updateMode !== 'click') {
            Ext.get(this.huePicker).moveTo(Ext.get(this.huePicker).getLeft(), Ext.get(this.cpGetId('hue')).getTop() + this.getHPos(Ext.getCmp(this.cpGetId('iHue')).getValue()) - 7, (this.animateMove || true));
            Ext.get(this.rgbPicker).moveTo(Ext.get(this.cpGetId('rgb')).getLeft() + this.getSPos(Ext.getCmp(this.cpGetId('iSat')).getValue() / 100) - 7, Ext.get(this.cpGetId('hue')).getTop() + this.getVPos(Ext.getCmp(this.cpGetId('iVal')).getValue() / 100) - 7, (this.animateMove || true));
        }

        Ext.get(this.cpGetId('rgb')).setStyle({
            'background-color': '#' + this.rgbToHex(this.hsvToRgb(Ext.getCmp(this.cpGetId('iHue')).getValue(), 1, 1))
        });

        this.fireEvent('update', this, this.getColor());
    },

    setColor: function(c, preventInit) {
        if (!/^[0-9a-fA-F]{6}$/.test(c)) return;
        var cmp = Ext.getCmp(this.cpGetId('iHexa'));
        if (cmp) {
            cmp.setValue(c);
            if (preventInit !== true) {
                Ext.get(this.cpGetId('cOriginal')).setStyle({
                    'background': '#' + c
                });
                this.initColor = c;
            }
            this.updateFromIHexa();
        }
    },

    getColor: function() {
        return Ext.getCmp(this.cpGetId('iHexa')).getValue();
    },

    updateFromIRGB: function(input, newValue, oldValue) {
        this.updateMode = 'rgb';
        var temp = this.rgbToHsv(Ext.getCmp(this.cpGetId('iRed')).getValue(), Ext.getCmp(this.cpGetId('iGreen')).getValue(), Ext.getCmp(this.cpGetId('iBlue')).getValue());
        this.HSV = {
            h: temp[0],
            s: temp[1],
            v: temp[2]
        };
        this.updateColor();
    },
    updateFromIHSV: function(input, newValue, oldValue) {
        this.updateMode = 'hsv';
        this.HSV = {
            h: Ext.getCmp(this.cpGetId('iHue')).getValue(),
            s: Ext.getCmp(this.cpGetId('iSat')).getValue() / 100,
            v: Ext.getCmp(this.cpGetId('iVal')).getValue() / 100
        };
        this.updateColor();
    },

    updateFromIHexa: function(input, e) {
        var value = Ext.getCmp(this.cpGetId('iHexa')).getValue();
        if (!/^[0-9a-fA-F]{6}$/.test(value)) return;

        this.updateMode = 'hexa';
        var temp = this.rgbToHsv(this.hexToRgb(value));
        this.HSV = {
            h: temp[0],
            s: temp[1],
            v: temp[2]
        };
        this.updateColor();
    },

    updateFromBox: function(event, element) {
        this.updateMode = 'click';
        var temp = this.rgbToHsv(this.hexToRgb(Ext.get(element).getColor('backgroundColor', '', '')));
        this.HSV = {
            h: temp[0],
            s: temp[1],
            v: temp[2]
        };
        this.updateColor();
    },

    selectColor: function(event, element) {
        //this.fireEvent('select', this, Ext.get( element ).getColor( 'backgroundColor', '', '' ));
        this.fireEvent('select', this, this.getColor());
    },
    resetColor: function(event, element) {
        Ext.getCmp(this.cpGetId('iHexa')).setValue(this.initColor);
        this.updateFromIHexa();
    },
    /**
     * Convert HSV color format to RGB color format
     * @param {Integer/Array( h, s, v )} h
     * @param {Integer} s (optional)
     * @param {Integer} v (optional)
     * @return {Array}
     */
    hsvToRgb: function(h, s, v) {
        if (h instanceof Array) {
            return this.hsvToRgb.call(this, h[0], h[1], h[2]);
        }
        var r, g, b, i, f, p, q, t;
        i = Math.floor((h / 60) % 6);
        f = (h / 60) - i;
        p = v * (1 - s);
        q = v * (1 - f * s);
        t = v * (1 - (1 - f) * s);
        switch (i) {
        case 0:
            r = v;
            g = t;
            b = p;
            break;
        case 1:
            r = q;
            g = v;
            b = p;
            break;
        case 2:
            r = p;
            g = v;
            b = t;
            break;
        case 3:
            r = p;
            g = q;
            b = v;
            break;
        case 4:
            r = t;
            g = p;
            b = v;
            break;
        case 5:
            r = v;
            g = p;
            b = q;
            break;
        }
        return [this.realToDec(r), this.realToDec(g), this.realToDec(b)];
    },
    /**
     * Convert RGB color format to HSV color format
     * @param {Integer/Array( r, g, b )} r
     * @param {Integer} g (optional)
     * @param {Integer} b (optional)
     * @return {Array}
     */
    rgbToHsv: function(r, g, b) {
        if (r instanceof Array) {
            return this.rgbToHsv.call(this, r[0], r[1], r[2]);
        }
        r = r / 255;
        g = g / 255;
        b = b / 255;
        var min, max, delta, h, s, v;
        min = Math.min(Math.min(r, g), b);
        max = Math.max(Math.max(r, g), b);
        delta = max - min;
        switch (max) {
        case min:
            h = 0;
            break;
        case r:
            h = 60 * (g - b) / delta;
            if (g < b) {
                h += 360;
            }
            break;
        case g:
            h = (60 * (b - r) / delta) + 120;
            break;
        case b:
            h = (60 * (r - g) / delta) + 240;
            break;
        }
        s = (max === 0) ? 0 : 1 - (min / max);
        return [Math.round(h), s, max];
    },
    /**
     * Convert a float to decimal
     * @param {Float} n
     * @return {Integer}
     */
    realToDec: function(n) {
        return Math.min(255, Math.round(n * 256));
    },
    /**
     * Convert RGB color format to Hexa color format
     * @param {Integer/Array( r, g, b )} r
     * @param {Integer} g (optional)
     * @param {Integer} b (optional)
     * @return {String}
     */
    rgbToHex: function(r, g, b) {
        if (r instanceof Array) {
            return this.rgbToHex.call(this, r[0], r[1], r[2]);
        }
        return this.decToHex(r) + this.decToHex(g) + this.decToHex(b);
    },
    /**
     * Convert an integer to hexa
     * @param {Integer} n
     * @return {String}
     */
    decToHex: function(n) {
        var HCHARS = '0123456789ABCDEF';
        n = parseInt(n, 10);
        n = (!isNaN(n)) ? n: 0;
        n = (n > 255 || n < 0) ? 0 : n;
        return HCHARS.charAt((n - n % 16) / 16) + HCHARS.charAt(n % 16);
    },
    /**
     * Return with position of a character in this.HCHARS string
     * @private
     * @param {Char} c
     * @return {Integer}
     */
    getHCharPos: function(c) {
        var HCHARS = '0123456789ABCDEF';
        return HCHARS.indexOf(c.toUpperCase());
    },
    /**
     * Convert a hexa string to decimal
     * @param {String} hex
     * @return {Integer}
     */
    hexToDec: function(hex) {
        var s = hex.split('');
        return ((this.getHCharPos(s[0]) * 16) + this.getHCharPos(s[1]));
    },
    /**
     * Convert a hexa string to RGB color format
     * @param {String} hex
     * @return {Array}
     */
    hexToRgb: function(hex) {
        return [this.hexToDec(hex.substr(0, 2)), this.hexToDec(hex.substr(2, 2)), this.hexToDec(hex.substr(4, 2))];
    },
    /**
     * Convert Y coordinate to HUE value
     * @private
     * @param {Integer} y
     * @return {Integer}
     */
    getHue: function(y) {
        var hue = 360 - Math.round(((181 - y) / 181) * 360);
        return hue === 360 ? 0 : hue;
    },
    /**
     * Convert HUE value to Y coordinate
     * @private
     * @param {Integer} hue
     * @return {Integer}
     */
    getHPos: function(hue) {
        return 181 - hue * (181 / 360);
    },
    /**
     * Convert X coordinate to Saturation value
     * @private
     * @param {Integer} x
     * @return {Integer}
     */
    getSaturation: function(x) {
        return x / 181;
    },
    /**
 * Convert Saturation value to Y coordinate
 * @private
 * @param {Integer} saturation
 * @return {Integer}
 */
    getSPos: function(saturation) {
        return saturation * 181;
    },
    /**
 * Convert Y coordinate to Brightness value
 * @private
 * @param {Integer} y
 * @return {Integer}
 */
    getValue: function(y) {
        return (181 - y) / 181;
    },
    /**
 * Convert Brightness value to Y coordinate
 * @private
 * @param {Integer} value
 * @return {Integer}
 */
    getVPos: function(value) {
        return 181 - (value * 181);
    },
    /**
 * Not documented yet
 */
    checkSafeNumber: function(v) {
        if (!isNaN(v)) {
            v = Math.min(Math.max(0, v), 255);
            var i, next;
            for (i = 0; i < 256; i = i + 51) {
                next = i + 51;
                if (v >= i && v <= next) {
                    return (v - i > 25) ? next: i;
                }
            }
        }
        return v;
    },
    /**
 * Not documented yet
 */
    websafe: function(r, g, b) {
        if (r instanceof Array) {
            return this.websafe.call(this, r[0], r[1], r[2]);
        }
        return [this.checkSafeNumber(r), this.checkSafeNumber(g), this.checkSafeNumber(b)];
    },
    /**
     * Not documented yet
     */
    invert: function(r, g, b) {
        if (r instanceof Array) {
            return this.invert.call(this, r[0], r[1], r[2]);
        }
        return [255 - r, 255 - g, 255 - b];
    }
});
/**
 * @class Ext.ux.ColorDialog
 * @extends Ext.Window
 */
Ext.ux.ColorDialog = Ext.extend(Ext.Window, {
    constructor: function(config) {
        config = config || {};
        Ext.applyIf(config, {
            buttons: [{
                handler: this.onOk,
                scope: this,
                text: 'Ok'
            },
            {
                handler: this.onCancel,
                scope: this,
                text: 'Cancel'
            }],
            height: 270,
            modal: true,
            width: 355
        });
        Ext.ux.ColorDialog.superclass.constructor.apply(this, [config]);
    },
    initComponent: function() {
        this.width = (!this.width || this.width < 353) ? 353 : this.width;
        this.applyDefaultsCP();
        Ext.ux.ColorDialog.superclass.initComponent.apply(this, arguments);
    },
    onRender: function() {
        Ext.ux.ColorDialog.superclass.onRender.apply(this, arguments);
        this.renderComponent();
    },
    onOk: function() {
        //this.selectColor(); // will fire the 'select' event
        if (this.callback && this.scope) {
            this.callback.call(this.scope, this.getColor());
        }
        this[this.closeAction]();
    },
    onCancel: function() {
        this.fireEvent('cancel', this);
        this[this.closeAction]();
    },
    show: function(hex, cb, scope) { // override the superclass show() so the callback is not called from show()
        if (!this.rendered) {
            this.render(Ext.getBody());
        }
        if (this.hidden === false) {
            this.toFront();
            return;
        }
        if (this.fireEvent("beforeshow", this) === false) {
            return;
        }
        if (cb) {
            this.callback = cb;
        }
        if (scope) {
            this.scope = scope;
        }
        this.hidden = false;
        this.beforeShow();
        this.afterShow();
        hex = hex || '000000';
        this.setColor(hex);
    }
});
Ext.applyIf(Ext.ux.ColorDialog.prototype, Ext.ux.ColorPicker.prototype);
/**
 *
 */
Ext.ux.ColorPanel = Ext.extend(Ext.Panel, {
    initComponent: function() {
        this.width = (!this.width || this.width < 300) ? 300 : this.width;
        this.applyDefaultsCP();
        Ext.ux.ColorPanel.superclass.initComponent.apply(this, arguments);
    },
    onRender: function() {
        Ext.ux.ColorPanel.superclass.onRender.apply(this, arguments);
        this.renderComponent();
    }
});
Ext.applyIf(Ext.ux.ColorPanel.prototype, Ext.ux.ColorPicker.prototype);
/**
 * Register Color* for Lazy Rendering
 */
Ext.reg('colorpicker', Ext.ux.ColorPicker);
Ext.reg('colordialog', Ext.ux.ColorDialog);
Ext.reg('colorpanel', Ext.ux.ColorPanel);
/*
 * @class Ext.ux.grid.ExplorerView
 * @extends Ext.grid.GridView
 *
 * Code is from Ext.ux.grid.ExplorerView of the Ext JS forums.
 *
 * A rewrite that works better with Ext JS 3.0.
 *
 * Example Usage:
var detailedIcons = new Ext.Template(
    '<div class="x-grid3-row ux-explorerview-detailed-icon-row {alt}">',
    '<table class="x-grid3-row-table"><tbody><tr><td class="x-grid3-col x-grid3-cell ux-explorerview-icon"><img src="images/medium-{icon}"></td>',
    '<td class="x-grid3-col x-grid3-cell"><div class="x-grid3-cell-inner" unselectable="on">{name}<br><span>{type}<br>{size}</span></div></td></tr>',
    '</tbody></table></div>'
);
var grid = new Ext.grid.GridPanel({
   store: ...
   , columns: ...
   , view: new Ext.ux.grid.ExplorerView({
      rowTemplate: detailedIcons
   })
   , enableDragDrop: true
   , autoExpandColumn: 'name'
   , ...
});
 *
 */
Ext.ns('Ext.ux.grid');
Ext.ux.grid.ExplorerView = Ext.extend(Ext.grid.GridView, {
    /**
     * @cfg {Ext.Template} Template to use when rendering rows, null if default grid row rendering
     */
    rowTemplate: null,

    /**
     * Changes the current row-template and refreshes the view.
     * @param {Ext.Template} template Use this template, set to null if you want grid default row rendering.
     */
    changeTemplate: function(template) {
        this.rowTemplate = template;
        this.initTemplates();
        this.refresh();
    },

    initTemplates: function() {
        Ext.ux.grid.ExplorerView.superclass.initTemplates.apply(this, arguments);

        // Store original row template
        if (!this.templates.orgrow) this.templates.orgrow = this.templates.row;

        if (this.rowTemplate != null) this.templates.row = this.rowTemplate.compile();
        else this.templates.row = this.templates.orgrow;
    },

    doRender: function(cs, rs, ds, startRow, colCount, stripe) {
        if (this.rowTemplate == null) {
            // Let GridView class handle "normal" rows
            return Ext.ux.grid.ExplorerView.superclass.doRender.apply(this, arguments);
        } else {
            var ts = this.templates,
            rt = ts.row;
            // buffers
            var buf = [],
            r,
            c,
            p = {};
            for (var j = 0,
            len = rs.length; j < len; j++) {
                r = rs[j];

                // Make sure we get data that isnt visible also.
                for (var i = 0; i < r.fields.items.length; i++) p[r.fields.items[i].name] = r.data[r.fields.items[i].name];

                // Use the column renderer if any
                var rowIndex = (j + startRow);
                for (var i = 0; i < colCount; i++) {
                    p[cs[i].name] = cs[i].renderer(r.data[cs[i].name], p, r, rowIndex, i, ds);
                    if (p[cs[i].name] == undefined || p[cs[i].name] === "") p[cs[i].name] = "&#160;";
                }

                buf[buf.length] = rt.apply(p);
            }
            return buf.join("");
        }
    },

    updateAllColumnWidths: function() {
        if (this.rowTemplate == null) {
            // Let GridView class handle "normal" rows
            return Ext.ux.grid.ExplorerView.superclass.updateAllColumnWidths.apply(this, arguments);
        } else {
            var tw = this.getTotalWidth();
            var clen = this.cm.getColumnCount();
            var ws = [];
            for (var i = 0; i < clen; i++) {
                ws[i] = this.getColumnWidth(i);
            }
            this.innerHd.firstChild.style.width = this.getOffsetWidth();
            this.innerHd.firstChild.firstChild.style.width = tw;
            this.mainBody.dom.style.width = tw;
            for (var i = 0; i < clen; i++) {
                var hd = this.getHeaderCell(i);
                hd.style.width = ws[i];
            }

            this.onAllColumnWidthsUpdated(ws, tw);
        }
    },

    updateColumnWidth: function(col, width) {
        if (this.rowTemplate == null) {
            // Let GridView class handle "normal" rows
            return Ext.ux.grid.ExplorerView.superclass.updateColumnWidth.apply(this, arguments);
        } else {
            var w = this.getColumnWidth(col);
            var tw = this.getTotalWidth();
            this.innerHd.firstChild.style.width = this.getOffsetWidth();
            this.innerHd.firstChild.firstChild.style.width = tw;
            this.mainBody.dom.style.width = tw;
            var hd = this.getHeaderCell(col);
            hd.style.width = w;

            this.onColumnWidthUpdated(col, w, tw);
        }
    },

    updateColumnHidden: function(col, hidden) {
        if (this.rowTemplate == null) {
            // Let GridView class handle "normal" rows
            return Ext.ux.grid.ExplorerView.superclass.updateColumnHidden.apply(this, arguments);
        } else {
            var tw = this.getTotalWidth();
            this.innerHd.firstChild.style.width = this.getOffsetWidth();
            this.innerHd.firstChild.firstChild.style.width = tw;
            //this.mainBody.dom.style.width = tw;
            var display = hidden ? 'none': '';
            var hd = this.getHeaderCell(col);
            hd.style.display = display;

            this.onColumnHiddenUpdated(col, hidden, tw);
            delete this.lastViewWidth; // force recalc
            //this.layout();
        }
    }
});
Ext.ns('Ext.ux.grid');

Ext.ux.grid.GroupingExplorerView = Ext.extend(Ext.ux.grid.ExplorerView, {
    hideGroupedColumn: false,
    showGroupName: true,
    startCollapsed: false,
    enableGrouping: true,
    enableGroupingMenu: true,
    enableNoGroups: true,
    emptyGroupText: '(None)',
    ignoreAdd: false,
    groupTextTpl: '{text}',

    // private
    gidSeed: 1000,

    // private
    initTemplates: function() {
        Ext.ux.grid.GroupingExplorerView.superclass.initTemplates.call(this);
        this.state = {};

        var sm = this.grid.getSelectionModel();
        sm.on(sm.selectRow ? 'beforerowselect': 'beforecellselect', this.onBeforeRowSelect, this);

        if (!this.startGroup) {
            this.startGroup = new Ext.XTemplate('<div id="{groupId}" class="x-grid-group {cls}">', '<div id="{groupId}-hd" class="x-grid-group-hd" style="{style}"><div>', this.groupTextTpl, '</div></div>', '<div id="{groupId}-bd" class="x-grid-group-body x-grid-group-body-floatcontainer">');
        }
        this.startGroup.compile();
        this.endGroup = '</div></div>';
    },

    // private
    findGroup: function(el) {
        return Ext.fly(el).up('.x-grid-group', this.mainBody.dom);
    },

    // private
    getGroups: function() {
        return this.hasRows() ? this.mainBody.dom.childNodes: [];
    },

    // private
    onAdd: function() {
        if (this.enableGrouping && !this.ignoreAdd) {
            var ss = this.getScrollState();
            this.refresh();
            this.restoreScroll(ss);
        } else if (!this.enableGrouping) {
            Ext.ux.grid.GroupingExplorerView.superclass.onAdd.apply(this, arguments);
        }
    },

    // private
    onRemove: function(ds, record, index, isUpdate) {
        Ext.ux.grid.GroupingExplorerView.superclass.onRemove.apply(this, arguments);
        var g = document.getElementById(record._groupId);
        if (g && g.childNodes[1].childNodes.length < 1) {
            Ext.removeNode(g);
        }
        this.applyEmptyText();
    },

    // private
    refreshRow: function(record) {
        if (this.ds.getCount() == 1) {
            this.refresh();
        } else {
            this.isUpdating = true;
            Ext.ux.grid.GroupingExplorerView.superclass.refreshRow.apply(this, arguments);
            this.isUpdating = false;
        }
    },

    // private
    beforeMenuShow: function() {
        var field = this.getGroupField();
        var g = this.hmenu.items.get('groupBy');
        if (g) {
            g.setDisabled(this.cm.config[this.hdCtxIndex].groupable === false);
        }
        var s = this.hmenu.items.get('showGroups');
        if (s) {
            s.setDisabled(!field && this.cm.config[this.hdCtxIndex].groupable === false);
            s.setChecked( !! field, true);
        }
    },

    // private
    renderUI: function() {
        Ext.ux.grid.GroupingExplorerView.superclass.renderUI.call(this);
        this.mainBody.on('mousedown', this.interceptMouse, this);

        if (this.enableGroupingMenu && this.hmenu) {
            this.hmenu.add('-', {
                id: 'groupBy',
                text: this.groupByText,
                handler: this.onGroupByClick,
                scope: this,
                iconCls: 'x-group-by-icon'
            });
            if (this.enableNoGroups) {
                this.hmenu.add({
                    id: 'showGroups',
                    text: this.showGroupsText,
                    checked: true,
                    checkHandler: this.onShowGroupsClick,
                    scope: this
                });
            }
            this.hmenu.on('beforeshow', this.beforeMenuShow, this);
        }
    },

    // private
    onGroupByClick: function() {
        this.grid.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex));
        this.beforeMenuShow(); // Make sure the checkboxes get properly set when changing groups
    },

    // private
    onShowGroupsClick: function(mi, checked) {
        if (checked) {
            this.onGroupByClick();
        } else {
            this.grid.store.clearGrouping();
        }
    },

    toggleGroup: function(group, expanded) {
        this.grid.stopEditing(true);
        group = Ext.getDom(group);
        var gel = Ext.fly(group);
        expanded = expanded !== undefined ? expanded: gel.hasClass('x-grid-group-collapsed');

        this.state[gel.dom.id] = expanded;
        gel[expanded ? 'removeClass': 'addClass']('x-grid-group-collapsed');
    },

    toggleAllGroups: function(expanded) {
        var groups = this.getGroups();
        for (var i = 0,
        len = groups.length; i < len; i++) {
            this.toggleGroup(groups[i], expanded);
        }
    },

    expandAllGroups: function() {
        this.toggleAllGroups(true);
    },

    collapseAllGroups: function() {
        this.toggleAllGroups(false);
    },

    // private
    interceptMouse: function(e) {
        var hd = e.getTarget('.x-grid-group-hd', this.mainBody);
        if (hd) {
            e.stopEvent();
            this.toggleGroup(hd.parentNode);
        }
    },

    // private
    getGroup: function(v, r, groupRenderer, rowIndex, colIndex, ds) {
        var g = groupRenderer ? groupRenderer(v, {},
        r, rowIndex, colIndex, ds) : String(v);
        if (g === '') {
            g = this.cm.config[colIndex].emptyGroupText || this.emptyGroupText;
        }
        return g;
    },

    // private
    getGroupField: function() {
        return this.grid.store.getGroupState();
    },

    // private
    renderRows: function() {
        var groupField = this.getGroupField();
        var eg = !!groupField;
        // if they turned off grouping and the last grouped field is hidden
        if (this.hideGroupedColumn) {
            var colIndex = this.cm.findColumnIndex(groupField);
            if (!eg && this.lastGroupField !== undefined) {
                this.mainBody.update('');
                this.cm.setHidden(this.cm.findColumnIndex(this.lastGroupField), false);
                delete this.lastGroupField;
            } else if (eg && this.lastGroupField === undefined) {
                this.lastGroupField = groupField;
                this.cm.setHidden(colIndex, true);
            } else if (eg && this.lastGroupField !== undefined && groupField !== this.lastGroupField) {
                this.mainBody.update('');
                var oldIndex = this.cm.findColumnIndex(this.lastGroupField);
                this.cm.setHidden(oldIndex, false);
                this.lastGroupField = groupField;
                this.cm.setHidden(colIndex, true);
            }
        }
        return Ext.ux.grid.GroupingExplorerView.superclass.renderRows.apply(this, arguments);
    },

    // private
    doRender: function(cs, rs, ds, startRow, colCount, stripe) {
        if (rs.length < 1) {
            return '';
        }
        var groupField = this.getGroupField();
        var colIndex = this.cm.findColumnIndex(groupField);

        this.enableGrouping = !!groupField;

        if (!this.enableGrouping || this.isUpdating) {
            return Ext.ux.grid.GroupingExplorerView.superclass.doRender.apply(this, arguments);
        }
        var gstyle = 'width:' + this.getTotalWidth() + ';';

        var gidPrefix = this.grid.getGridEl().id;
        var cfg = this.cm.config[colIndex];
        var groupRenderer = cfg.groupRenderer || cfg.renderer;
        var prefix = this.showGroupName ? (cfg.groupName || cfg.header) + ': ': '';

        var groups = [],
        curGroup,
        i,
        len,
        gid;
        for (i = 0, len = rs.length; i < len; i++) {
            var rowIndex = startRow + i;
            var r = rs[i],
            gvalue = r.data[groupField],
            g = this.getGroup(gvalue, r, groupRenderer, rowIndex, colIndex, ds);
            if (!curGroup || curGroup.group != g) {
                gid = gidPrefix + '-gp-' + groupField + '-' + Ext.util.Format.htmlEncode(g);
                // if state is defined use it, however state is in terms of expanded
                // so negate it, otherwise use the default.
                var isCollapsed = typeof this.state[gid] !== 'undefined' ? !this.state[gid] : this.startCollapsed;
                var gcls = isCollapsed ? 'x-grid-group-collapsed': '';
                curGroup = {
                    group: g,
                    gvalue: gvalue,
                    text: prefix + g,
                    groupId: gid,
                    startRow: rowIndex,
                    rs: [r],
                    cls: gcls,
                    style: gstyle
                };
                groups.push(curGroup);
            } else {
                curGroup.rs.push(r);
            }
            r._groupId = gid;
        }

        var buf = [];
        for (i = 0, len = groups.length; i < len; i++) {
            var g = groups[i];
            this.doGroupStart(buf, g, cs, ds, colCount);
            buf[buf.length] = Ext.ux.grid.GroupingExplorerView.superclass.doRender.call(this, cs, g.rs, ds, g.startRow, colCount, stripe);

            this.doGroupEnd(buf, g, cs, ds, colCount);
        }
        return buf.join('');
    },

    getGroupId: function(value) {
        var gidPrefix = this.grid.getGridEl().id;
        var groupField = this.getGroupField();
        var colIndex = this.cm.findColumnIndex(groupField);
        var cfg = this.cm.config[colIndex];
        var groupRenderer = cfg.groupRenderer || cfg.renderer;
        var gtext = this.getGroup(value, {
            data: {}
        },
        groupRenderer, 0, colIndex, this.ds);
        return gidPrefix + '-gp-' + groupField + '-' + Ext.util.Format.htmlEncode(value);
    },

    // private
    doGroupStart: function(buf, g, cs, ds, colCount) {
        buf[buf.length] = this.startGroup.apply(g);
    },

    // private
    doGroupEnd: function(buf, g, cs, ds, colCount) {
        buf[buf.length] = this.endGroup;
    },

    // private
    getRows: function() {
        if (!this.enableGrouping) {
            return Ext.ux.grid.GroupingExplorerView.superclass.getRows.call(this);
        }
        var r = [];
        var g, gs = this.getGroups();
        for (var i = 0,
        len = gs.length; i < len; i++) {
            g = gs[i].childNodes[1].childNodes;
            for (var j = 0,
            jlen = g.length; j < jlen; j++) {
                r[r.length] = g[j];
            }
        }
        return r;
    },

    // private
    updateGroupWidths: function() {
        if (!this.enableGrouping || !this.hasRows()) {
            return;
        }
        var tw = Math.max(this.cm.getTotalWidth(), this.el.dom.offsetWidth - this.scrollOffset) + 'px';
        var gs = this.getGroups();
        for (var i = 0,
        len = gs.length; i < len; i++) {
            gs[i].firstChild.style.width = tw;
        }
    },

    // private
    onColumnWidthUpdated: function(col, w, tw) {
        this.updateGroupWidths();
    },

    // private
    onAllColumnWidthsUpdated: function(ws, tw) {
        this.updateGroupWidths();
    },

    // private
    onColumnHiddenUpdated: function(col, hidden, tw) {
        this.updateGroupWidths();
    },

    // private
    onLayout: function() {
        this.updateGroupWidths();
    },
    // private
    onBeforeRowSelect: function(sm, rowIndex) {
        if (!this.enableGrouping) {
            return;
        }
        var row = this.getRow(rowIndex);
        if (row && !row.offsetParent) {
            var g = this.findGroup(row);
            this.toggleGroup(g, true);
        }
    },

    groupByText: 'Group By This Field',
    showGroupsText: 'Show in Groups'
});

// Reg for lazy loading (xtype)
Ext.reg('groupingexplorerview', Ext.ux.grid.GroupingExplorerView);

// private
Ext.ux.grid.GroupingExplorerView.GROUP_ID = 1000;
Ext.namespace("Ext.plugin");
Ext.plugin.ModalNotice = Ext.extend(Ext.util.Observable, {
    init: function(win) {
        this.window = win;
        this.window.on('render',
        function() {
            if (this.window.modal === true) {
                this.mask = this.window.container.select('div.ext-el-mask');
                this.mask.applyStyles('opacity: 0.0');
                this.mask.on('click', this.onMaskClick, this);
            }
        },
        this);
    },
    onMaskClick: function() {
        this.mask.applyStyles('opacity: 0.5'); (function() {
            this.mask.applyStyles('opacity: 0.0');
        }).defer(250, this);
    }
});
/*
 * qWikiOffice Desktop 1.0
 * Copyright(c) 2007-2008, Integrated Technologies, Inc.
 * licensing@qwikioffice.com
 * 
 * http://www.qwikioffice.com/license
 */

Ext.namespace("Ext.plugin");
QoDesk.QoPreferences = Ext.extend(Ext.app.Module, {
    id: 'qo-preferences',
    type: 'system/preferences',
    cardHistory: ['pref-win-card-1']

    ,
    init: function() {
        this.locale = QoDesk.QoPreferences.Locale;
    }

    ,
    createWindow: function() {
        var d = this.app.getDesktop();
        this.win = d.getWindow(this.id);

        var h = parseInt(d.getWinHeight() * 0.9);
        var w = parseInt(d.getWinWidth() * 0.9);
        if (h > 500) {
            h = 500;
        }
        if (w > 610) {
            w = 610;
        }

        if (this.win) {
            this.win.setSize(w, h);
        } else {
            this.contentPanel = new Ext.Panel({
                activeItem: 0,
                border: false,
                items: [new QoDesk.QoPreferences.Nav({
                    ownerModule: this,
                    id: 'pref-win-card-1'
                }), new QoDesk.QoPreferences.Shortcuts({
                    ownerModule: this,
                    id: 'pref-win-card-6'
                }), new QoDesk.QoPreferences.AutoRun({
                    ownerModule: this,
                    id: 'pref-win-card-5'
                }), new QoDesk.QoPreferences.QuickStart({
                    ownerModule: this,
                    id: 'pref-win-card-2'
                }), new QoDesk.QoPreferences.Appearance({
                    ownerModule: this,
                    id: 'pref-win-card-3'
                }), new QoDesk.QoPreferences.Background({
                    ownerModule: this,
                    id: 'pref-win-card-4'
                })],
                layout: 'card',
                tbar: [{
                    disabled: true,
                    handler: this.navHandler.createDelegate(this, [ - 1]),
                    id: 'back',
                    scope: this,
                    text: this.locale.button.back.text
                },
                {
                    disabled: true,
                    handler: this.navHandler.createDelegate(this, [1]),
                    id: 'next',
                    scope: this,
                    text: this.locale.button.next.text
                }]
            });

            this.win = d.createWindow({
                animCollapse: false,
                constrainHeader: true,
                id: this.id,
                height: h,
                iconCls: 'qo-pref-icon',
                items: this.contentPanel,
                layout: 'fit',
                shim: false,
                taskbuttonTooltip: this.locale.launcher.tooltip,
                title: this.locale.title.window,
                width: w
            });

            this.layout = this.contentPanel.getLayout();
        }

        this.win.show();
    }

    ,
    handleButtonState: function() {
        var cards = this.cardHistory;
        var activeId = this.layout.activeItem.id;
        var items = this.contentPanel.getTopToolbar().items;
        var back = items.get(0);
        var next = items.get(1);

        for (var i = 0,
        len = cards.length; i < len; i++) {
            if (cards[i] === activeId) {
                if (i <= 0) {
                    back.disable();
                    next.enable();
                } else if (i >= (len - 1)) {
                    back.enable();
                    next.disable();
                } else {
                    back.enable();
                    next.enable();
                }
                break;
            }
        }
    }

    ,
    navHandler: function(index) {
        var cards = this.cardHistory;
        var activeId = this.layout.activeItem.id;
        var nextId;

        for (var i = 0,
        len = cards.length; i < len; i++) {
            if (cards[i] === activeId) {
                nextId = cards[i + index];
                break;
            }
        }

        this.layout.setActiveItem(nextId);
        this.handleButtonState();
    }

    ,
    save: function(params) {
        var desktop = this.app.getDesktop();
        var notifyWin = desktop.showNotification({
            html: this.locale.notification.saving.msg,
            title: this.locale.notification.saving.title
        });
        var callback = params.callback || null;
        var callbackScope = params.callbackScope || this;
        params.moduleId = this.id;

        Ext.Ajax.request({
            url: this.app.connection
            // Could also pass the module id and method in the querystring like this
            // instead of in the params config option.
            //
            // url: this.app.connection+'?modulId='+this.id+'&method=myMethod'
            ,
            params: params,
            success: function(o) {
                if (o && o.responseText && Ext.decode(o.responseText).success) {
                    saveComplete(this.locale.notification.saved.title, this.locale.notification.saved.msg);
                } else {
                    saveComplete(this.locale.error.title, this.locale.error.msg);
                }
            },
            failure: function() {
                saveComplete(this.locale.connection.lost.title, this.locale.connection.lost.msg);
            },
            scope: this
        });

        function saveComplete(title, msg) {
            notifyWin.setIconClass('x-icon-done');
            notifyWin.setTitle(title);
            notifyWin.setMessage(msg);
            desktop.hideNotification(notifyWin);

            if (callback) {
                callback.call(callbackScope);
            }
        }
    }

    ,
    viewCard: function(card) {
        this.layout.setActiveItem(card);
        var h = this.cardHistory;
        if (h.length > 1) {
            h.pop();
        }
        h.push(card);
        this.handleButtonState();
    }
});
/*

 * qWikiOffice Desktop 1.0
 * Copyright(c) 2007-2008, Integrated Technologies, Inc.
 * licensing@qwikioffice.com
 * 
 * http://www.qwikioffice.com/license
 */

QoDesk.QoPreferences.Appearance = Ext.extend(Ext.Panel, {
    constructor: function(config) {
        // constructor pre-processing
        config = config || {};

        this.ownerModule = config.ownerModule;

        var desktop = this.ownerModule.app.getDesktop();

        this.grid = new QoDesk.QoPreferences.Grid({
            border: true,
            cls: 'pref-card-subpanel pref-theme-groups',
            margins: '0 5 0 5',
            mode: 'themes',
            ownerModule: this.ownerModule,
            region: 'center'
        });

        this.slider = createSlider({
            handler: new Ext.util.DelayedTask(updateTransparency, this),
            min: 0,
            max: 100,
            x: 15,
            y: 40,
            width: 100
        });

        var formPanel = new Ext.FormPanel({
            border: false,
            height: 70,
            items: [{
                x: 15,
                y: 15,
                xtype: 'label',
                text: this.ownerModule.locale.label.transparency
            },
            this.slider.slider, this.slider.display, {
                x: 215,
                y: 15,
                xtype: 'label',
                text: this.ownerModule.locale.label.fontColor
            },
            {
                border: false,
                items: new Ext.Button({
                    iconCls: 'pref-font-color-icon',
                    handler: onChangeFontColor,
                    scope: this
                    //, text: this.ownerModule.locale.button.fontColor.text
                }),
                x: 215,
                y: 40
            }],
            layout: 'absolute',
            split: false,
            region: 'south'
        });

        // this config
        Ext.applyIf(config, {
            border: false,
            buttons: [{
                disabled: this.ownerModule.app.isAllowedTo('saveAppearance', this.ownerModule.id) ? false: true,
                handler: onSave,
                scope: this,
                text: this.ownerModule.locale.button.save.text
            },
            {
                handler: onClose,
                scope: this,
                text: this.ownerModule.locale.button.close.text
            }],
            cls: 'pref-card',
            items: [this.grid, formPanel],
            layout: 'border',
            title: this.ownerModule.locale.title.appearance
        });

        QoDesk.QoPreferences.Appearance.superclass.constructor.apply(this, [config]);
        // constructor post-processing
        function createSlider(config) {
            var handler = config.handler,
            min = config.min,
            max = config.max,
            width = config.width || 100,
            x = config.x,
            y = config.y;

            var slider = new Ext.Slider({
                minValue: min,
                maxValue: max,
                width: width,
                x: x,
                y: y
            });

            var display = new Ext.form.NumberField({
                cls: 'pref-percent-field',
                enableKeyEvents: true,
                maxValue: max,
                minValue: min,
                width: 45,
                x: x + width + 15,
                y: y - 1
            });

            function sliderHandler(slider) {
                var v = slider.getValue();
                display.setValue(v);
                handler.delay(100, null, null, [v]); // delayed task prevents IE bog
            }

            slider.on({
                'change': {
                    fn: sliderHandler,
                    scope: this
                },
                'drag': {
                    fn: sliderHandler,
                    scope: this
                }
            });

            display.on({
                'keyup': {
                    fn: function(field) {
                        var v = field.getValue();
                        if (v !== '' && !isNaN(v) && v >= field.minValue && v <= field.maxValue) {
                            slider.setValue(v);
                        }
                    },
                    buffer: 350,
                    scope: this
                }
            });

            return {
                slider: slider,
                display: display
            }
        }
        function onClose() {
            this.ownerModule.win.close();
        }

        function onSave() {
            var appearance = this.ownerModule.app.getDesktop().getAppearance();
            var data = {
                fontColor: appearance.fontColor,
                themeId: appearance.theme.id,
                taskbarTransparency: appearance.taskbarTransparency
            };

            this.buttons[0].disable();
            this.ownerModule.save({
                method: 'saveAppearance',
                callback: function() {
                    this.buttons[0].enable();
                },
                callbackScope: this,
                data: Ext.encode(data)
            });
        }

        function onSelectionChange(view, sel) {
            if (sel.length > 0) {
                var appearance = this.ownerModule.app.getDesktop().getAppearance();
                var cId = appearance.theme.id;
                var r = view.getRecord(sel[0]);
                var d = r.data;

                if (parseInt(cId) !== parseInt(r.id)) {
                    if (r && r.id && d.name && d.file) {
                        desktop.setTheme({
                            id: r.id,
                            name: d.name,
                            file: d.file
                        });
                    }
                }
            }
        }

        function onChangeFontColor() {
            var hex = this.ownerModule.app.getDesktop().getAppearance().fontColor;
            var dialog = new Ext.ux.ColorDialog({
                closeAction: 'close',
                iconCls: 'pref-font-color-icon',
                listeners: {
                    'cancel': {
                        fn: onFontColorCancel.createDelegate(this, [hex]),
                        scope: this
                    },
                    'select': {
                        fn: onFontColorSelect,
                        scope: this,
                        buffer: 350
                    },
                    'update': {
                        fn: onFontColorSelect,
                        scope: this,
                        buffer: 350
                    }
                },
                manager: this.ownerModule.app.getDesktop().getManager(),
                resizable: false,
                title: 'Pick A Font Color',
                modal: true,
                plugins: new Ext.plugin.ModalNotice()
            });
            dialog.show(hex);
        }

        function onFontColorSelect(p, hex) {
            desktop.setFontColor(hex);
        }

        function onFontColorCancel(hex) {
            desktop.setFontColor(hex);
        }

        function updateTransparency(v) {
            desktop.setTaskbarTransparency(v);
        }
    }

    // overrides
    ,
    afterRender: function() {
        QoDesk.QoPreferences.Appearance.superclass.afterRender.call(this);

        this.on('show', this.initAppearance, this, {
            single: true
        });
    }

    // added methods
    ,
    initAppearance: function() {
        this.grid.store.load();
        this.slider.slider.setValue(this.ownerModule.app.getDesktop().getAppearance().taskbarTransparency);
    }
});
/*
 * qWikiOffice Desktop 1.0
 * Copyright(c) 2007-2008, Integrated Technologies, Inc.
 * licensing@qwikioffice.com
 * 
 * http://www.qwikioffice.com/license
 */

QoDesk.QoPreferences.AutoRun = Ext.extend(Ext.Panel, {
    constructor: function(config) {
        // constructor pre-processing
        config = config || {};

        this.ownerModule = config.ownerModule;

        // this config
        Ext.applyIf(config, {
            border: false,
            buttons: [{
                disabled: this.ownerModule.app.isAllowedTo('saveAutorun', this.ownerModule.id) ? false: true,
                handler: onSave,
                scope: this,
                text: this.ownerModule.locale.button.save.text
            },
            {
                handler: onClose,
                scope: this,
                text: this.ownerModule.locale.button.close.text
            }],
            cls: 'pref-card',
            items: [{
                bodyStyle: 'padding:0 5px 0 0',
                border: false,
                html: this.ownerModule.locale.html.autorun,
                region: 'center',
                xtype: 'panel'
            },
            new QoDesk.QoPreferences.CheckTree({
                launcherKey: 'autorun',
                listeners: {
                    'checkchange': {
                        fn: onCheckChange,
                        scope: this
                    }
                },
                ownerModule: config.ownerModule,
                region: 'west'
            })],
            layout: 'border',
            title: this.ownerModule.locale.title.autorun
        });

        QoDesk.QoPreferences.AutoRun.superclass.constructor.apply(this, [config]);
        // constructor post-processing
        function onClose() {
            this.ownerModule.win.close();
        }

        function onSave() {
            this.buttons[0].disable();
            this.ownerModule.save({
                method: 'saveAutorun',
                callback: function() {
                    this.buttons[0].enable();
                },
                callbackScope: this,
                ids: Ext.encode(this.ownerModule.app.getDesktop().getLauncher('autorun'))
            });
        }

        function onCheckChange(node, checked) {
            if (node.leaf && node.id) {
                if (checked) {
                    this.ownerModule.app.desktop.addAutoRun(node.id, true);
                } else {
                    this.ownerModule.app.desktop.removeAutoRun(node.id, true);
                }
            }
        }
    }
});
/*
 * qWikiOffice Desktop 1.0
 * Copyright(c) 2007-2008, Integrated Technologies, Inc.
 * licensing@qwikioffice.com
 * 
 * http://www.qwikioffice.com/license
*/

QoDesk.QoPreferences.Background = Ext.extend(Ext.Panel, {
    constructor: function(config) {
        // constructor pre-processing
        config = config || {};

        this.ownerModule = config.ownerModule;

        var desktop = this.ownerModule.app.getDesktop();

        this.grid = new QoDesk.QoPreferences.Grid({
            border: true,
            cls: 'pref-card-subpanel pref-wallpaper-groups',
            margins: '0 5 0 5',
            mode: 'wallpapers',
            ownerModule: this.ownerModule,
            region: 'center'
        });

        var wpp = this.ownerModule.app.getDesktop().getBackground().wallpaperPosition;
        var tileRadio = createRadio('tile', wpp == 'tile' ? true: false, 90, 40);
        var centerRadio = createRadio('center', wpp == 'center' ? true: false, 200, 40);

        var position = new Ext.FormPanel({
            border: false,
            height: 100,
            items: [{
                x: 15,
                y: 15,
                xtype: 'label',
                text: this.ownerModule.locale.label.wallpaperPosition
            },
            {
                border: false,
                items: {
                    border: false,
                    html: '<img class="pref-bg-pos-tile" src="' + Ext.BLANK_IMAGE_URL + '" width="64" height="44" border="0" alt="" />'
                },
                x: 15,
                y: 40
            },
            tileRadio, {
                border: false,
                items: {
                    border: false,
                    html: '<img class="pref-bg-pos-center" src="' + Ext.BLANK_IMAGE_URL + '" width="64" height="44" border="0" alt="" />'
                },
                x: 125,
                y: 40
            },
            centerRadio, {
                x: 252,
                y: 15,
                xtype: 'label',
                text: this.ownerModule.locale.label.backgroundColor
            },
            {
                border: false,
                items: new Ext.Button({
                    iconCls: 'pref-bg-color-icon',
                    handler: onChangeBgColor,
                    scope: this
                    //, text: this.ownerModule.locale.button.backgroundColor.text
                }),
                x: 253,
                y: 40
            }],
            layout: 'absolute',
            region: 'south',
            split: false
        });

        // this config
        Ext.applyIf(config, {
            border: false,
            buttons: [{
                disabled: this.ownerModule.app.isAllowedTo('saveBackground', this.ownerModule.id) ? false: true,
                handler: onSave,
                scope: this,
                text: this.ownerModule.locale.button.save.text
            },
            {
                handler: onClose,
                scope: this,
                text: this.ownerModule.locale.button.close.text
            }],
            cls: 'pref-card',
            items: [this.grid, position],
            layout: 'border',
            title: this.ownerModule.locale.title.background
        });
        QoDesk.QoPreferences.Background.superclass.constructor.apply(this, [config]);
        // constructor post-processing
        function createRadio(value, checked, x, y) {
            if (value) {
                var radio = new Ext.form.Radio({
                    name: 'position',
                    inputValue: value,
                    checked: checked,
                    x: x,
                    y: y
                });
                radio.on('check', togglePosition, radio);
                return radio;
            }
            return null;
        }

        function onChangeBgColor() {
            var hex = this.ownerModule.app.getDesktop().getBackground().color;
            var dialog = new Ext.ux.ColorDialog({
                closeAction: 'close',
                iconCls: 'pref-bg-color-icon',
                listeners: {
                    'cancel': {
                        fn: onColorCancel.createDelegate(this, [hex]),
                        scope: this
                    },
                    'select': {
                        fn: onColorSelect,
                        scope: this,
                        buffer: 350
                    },
                    'update': {
                        fn: onColorSelect,
                        scope: this,
                        buffer: 350
                    }
                },
                manager: this.ownerModule.app.getDesktop().getManager(),
                resizable: false,
                title: 'Pick A Background Color',
                modal: true,
                plugins: new Ext.plugin.ModalNotice()
            });
            dialog.show(hex);
        }

        function onColorSelect(p, hex) {
            desktop.setBackgroundColor(hex);
        }

        function onColorCancel(hex) {
            desktop.setBackgroundColor(hex);
        }
        function onClose() {
            this.ownerModule.win.close();
        }

        function onSave() {
            var background = this.ownerModule.app.getDesktop().getBackground();
            var data = {
                color: background.color,
                wallpaperId: background.wallpaper.id,
                wallpaperPosition: background.wallpaperPosition
            };

            this.buttons[0].disable();
            this.ownerModule.save({
                method: 'saveBackground',
                callback: function() {
                    this.buttons[0].enable();
                },
                callbackScope: this,
                data: Ext.encode(data)
            });
        }

        function togglePosition(field, checked) {
            if (checked === true) {
                desktop.setWallpaperPosition(field.inputValue);
            }
        }
    }

    // overrides
    ,
    afterRender: function() {
        QoDesk.QoPreferences.Background.superclass.afterRender.call(this);

        this.on('show', this.loadGrid, this, {
            single: true
        });
    }

    // added methods
    ,
    loadGrid: function() {
        this.grid.store.load();
    }
});
QoDesk.QoPreferences.CheckTree = Ext.extend(Ext.tree.TreePanel, {
    /**
    * @cfg {String}
    */
    launcherKey: null

    ,
    constructor: function(config) {
        // constructor pre-processing
        config = config || {};
        this.launcherKey = config.launcherKey || null;

        this.ownerModule = config.ownerModule;

        var ms = this.ownerModule.app.modules;
        var ids = this.ownerModule.app.getDesktop().getLauncher(this.launcherKey);
        var nodes = expandNodes(ms, ids);

        // this config
        Ext.applyIf(config, {
            autoScroll: true,
            bodyStyle: 'padding:10px',
            border: true,
            cls: 'pref-card pref-check-tree',
            lines: false,
            loader: new Ext.tree.TreeLoader(),
            margins: '0 5 0 5',
            rootVisible: false,
            root: new Ext.tree.AsyncTreeNode({
                text: 'Hidden Root',
                children: nodes
            }),
            split: false,
            width: 220
        });

        QoDesk.QoPreferences.CheckTree.superclass.constructor.apply(this, [config]);
        // constructor post-processing
        this.on('checkchange', onCheckChange, this);

        new Ext.tree.TreeSorter(this, {
            dir: "asc"
        });

        function expandNodes(ms, ids) {
            var nodes = [];

            for (var i = 0,
            len = ms.length; i < len; i++) {
                if (ms[i].moduleType === 'menu') {
                    /* nodes.push({
                        leaf: false,
                        text: ms[i].launcher.text,
                        children: this.expandNodes(o.menu.items, ids)
                    }); */
                } else {
                    var checked = isChecked(ms[i].id, ids);
                    nodes.push({
                        checked: checked ? true: false,
                        cls: checked ? 'complete': null,
                        iconCls: ms[i].launcher.iconCls || '',
                        id: ms[i].id,
                        leaf: true,
                        selected: true,
                        text: ms[i].launcher.text
                    });
                }
            }

            return nodes;
        }

        function isChecked(id, ids) {
            for (var i = 0,
            len = ids.length; i < len; i++) {
                if (id == ids[i]) {
                    return true;
                }
            }
            return false;
        }

        function onCheckChange(node, checked) {
            if (checked) {
                node.getUI().addClass('complete');
            } else {
                node.getUI().removeClass('complete');
            }
            node.ownerTree.selModel.select(node);
        }
    }
});
/*
 * qWikiOffice Desktop 1.0
 * Copyright(c) 2007-2008, Integrated Technologies, Inc.
 * licensing@qwikioffice.com
 * 
 * http://www.qwikioffice.com/license
 */

QoDesk.QoPreferences.Grid = Ext.extend(Ext.grid.GridPanel, {
    mode: null // wallpapers or themes
    ,
    ownerModule: null

    ,
    constructor: function(config) {
        // constructor pre-processing
        config = config || {};

        this.ownerModule = config.ownerModule;
        this.mode = config.mode;

        var reader = new Ext.data.JsonReader({
            fields: ['group', 'id', 'name', 'thumbnail', 'file'],
            id: 'id',
            root: this.mode //'wallpapers'
        });

        var largeIcons = new Ext.Template('<div class="x-grid3-row ux-explorerview-item ux-explorerview-large-item" unselectable="on">' + '<table class="ux-explorerview-icon" cellpadding="0" cellspacing="0">' + '<tr><td align="center"><img src="{thumbnail}"></td></tr></table>' + '<div class="ux-explorerview-text"><div class="x-grid3-cell x-grid3-td-name" unselectable="on">{name}</div></div></div>');

        // this config
        Ext.applyIf(config, {
            columns: [{
                header: 'Group',
                width: 40,
                sortable: true,
                dataIndex: 'group'
            },
            {
                header: 'Name',
                sortable: true,
                dataIndex: 'name'
            }],
            enableDragDrop: false,
            hideHeaders: true,
            sm: new Ext.grid.RowSelectionModel({
                listeners: {
                    'rowselect': {
                        fn: this.onRowSelect,
                        scope: this
                    }
                },
                singleSelect: true
            }),
            store: new Ext.data.GroupingStore({
                baseParams: {
                    method: (this.mode === 'themes' ? 'viewThemes': 'viewWallpapers'),
                    moduleId: this.ownerModule.id
                },
                groupField: 'group',
                listeners: {
                    'load': {
                        fn: this.selectRecord,
                        scope: this
                    }
                },
                reader: reader,
                sortInfo: {
                    field: 'name',
                    direction: 'ASC'
                },
                url: config.ownerModule.app.connection

            }),
            view: new Ext.ux.grid.ExplorerView({
                //, view: new Ext.ux.grid.GroupingExplorerView({
                rowTemplate: largeIcons,
                forceFit: true
                //, groupTextTpl: '{text} ({[values.rs.length]})'
                //, showGroupName: false
            })
        });

        QoDesk.QoPreferences.Grid.superclass.constructor.apply(this, [config]);
        // constructor post-processing
        this.desktop = this.ownerModule.app.getDesktop();
    }

    // added methods
    ,
    onRowSelect: function(sm, index, record) {
        var r = record;
        var d = r.data;
        var id;
        var desktop = this.ownerModule.app.getDesktop();

        if (this.mode === 'themes') {
            id = desktop.getAppearance().theme.id;
        } else {
            id = desktop.getBackground().wallpaper.id;
        }
        if (parseInt(id) !== parseInt(r.id)) {
            if (r && r.id && d.name && d.file) {
                config = {
                    id: r.id,
                    name: d.name,
                    file: d.file
                };

                if (this.mode === 'themes') {
                    this.desktop.setTheme(config);
                } else {
                    this.desktop.setWallpaper(config);
                }
            }
        }
    }

    ,
    selectRecord: function() {
        var id;
        var desktop = this.ownerModule.app.getDesktop();

        if (this.mode === 'themes') {
            id = desktop.getAppearance().theme.id;
        } else {
            id = desktop.getBackground().wallpaper.id;
        }

        this.selModel.selectRecords([this.store.getById(id)]);
    }
});
/*
 * qWikiOffice Desktop 1.0
 * Copyright(c) 2007-2008, Integrated Technologies, Inc.
 * licensing@qwikioffice.com
 * 
 * http://www.qwikioffice.com/license
 */

QoDesk.QoPreferences.Nav = Ext.extend(Ext.Panel, {
    constructor: function(config) {
        // constructor pre-processing
        config = config || {};

        this.ownerModule = config.ownerModule;

        this.actions = {
            'viewShortcuts': function(ownerModule) {
                ownerModule.viewCard('pref-win-card-6');
            },
            'viewAutoRun': function(ownerModule) {
                ownerModule.viewCard('pref-win-card-5');
            },
            'viewQuickstart': function(ownerModule) {
                ownerModule.viewCard('pref-win-card-2');
            },
            'viewAppearance': function(ownerModule) {
                ownerModule.viewCard('pref-win-card-3');
            },
            'viewWallpapers': function(ownerModule) {
                ownerModule.viewCard('pref-win-card-4');
            }
        };

        // this config
        Ext.applyIf(config, {
            autoScroll: true,
            bodyStyle: 'padding:15px',
            border: false
        });

        QoDesk.QoPreferences.Nav.superclass.constructor.apply(this, [config]);
        // constructor post-processing
    }

    // overrides
    ,
    afterRender: function() {
        var tpl = new Ext.XTemplate('<ul class="pref-nav-list">', '<tpl for=".">', '<li><div>', '<div class="prev-link-item-icon"><img src="' + Ext.BLANK_IMAGE_URL + '" class="{cls}"/></div>', '<div class="prev-link-item-txt"><a id="{id}" href="#">{text}</a><br />{description}</div>', '<div class="x-clear"></div>', '</div></li>', '</tpl>', '</ul>');
        tpl.overwrite(this.body, this.ownerModule.locale.data.nav);

        this.body.on({
            'mousedown': {
                fn: this.doAction,
                scope: this,
                delegate: 'a'
            },
            'click': {
                fn: Ext.emptyFn,
                scope: null,
                delegate: 'a',
                preventDefault: true
            }
        });

        QoDesk.QoPreferences.Nav.superclass.afterRender.call(this); // do sizing calcs last
    }

    // added methods
    ,
    doAction: function(e, t) {
        e.stopEvent();
        this.actions[t.id](this.ownerModule); // pass ownerModule for scope
    }
});
/*
 * qWikiOffice Desktop 1.0
 * Copyright(c) 2007-2008, Integrated Technologies, Inc.
 * licensing@qwikioffice.com
 * 
 * http://www.qwikioffice.com/license
 */

QoDesk.QoPreferences.QuickStart = Ext.extend(Ext.Panel, {
    constructor: function(config) {
        // constructor pre-processing
        config = config || {};

        this.ownerModule = config.ownerModule;

        // this config
        Ext.applyIf(config, {
            border: false,
            buttons: [{
                disabled: this.ownerModule.app.isAllowedTo('saveQuickstart', this.ownerModule.id) ? false: true,
                handler: onSave,
                scope: this,
                text: 'Save'
            },
            {
                handler: onClose,
                scope: this,
                text: 'Close'
            }],
            cls: 'pref-card',
            items: [{
                bodyStyle: 'padding:0 5px 0 0',
                border: false,
                html: this.ownerModule.locale.html.quickstart,
                region: 'center',
                xtype: 'panel'
            },
            new QoDesk.QoPreferences.CheckTree({
                launcherKey: 'quickstart',
                listeners: {
                    'checkchange': {
                        fn: onCheckChange,
                        scope: this
                    }
                },
                ownerModule: config.ownerModule,
                region: 'west'
            })],
            layout: 'border',
            title: this.ownerModule.locale.title.quickstart
        });

        QoDesk.QoPreferences.QuickStart.superclass.constructor.apply(this, [config]);
        // constructor post-processing
        function onClose() {
            this.ownerModule.win.close();
        }

        function onSave() {
            this.buttons[0].disable();
            this.ownerModule.save({
                method: 'saveQuickstart',
                callback: function() {
                    this.buttons[0].enable();
                },
                callbackScope: this,
                ids: Ext.encode(this.ownerModule.app.getDesktop().getLauncher('quickstart'))
            });
        }

        function onCheckChange(node, checked) {
            if (node.leaf && node.id) {
                if (checked) {
                    this.ownerModule.app.desktop.addQuickStartButton(node.id, true);
                } else {
                    this.ownerModule.app.desktop.removeQuickStartButton(node.id, true);
                }
            }
        }
    }
});
/*
 * qWikiOffice Desktop 1.0
 * Copyright(c) 2007-2008, Integrated Technologies, Inc.
 * licensing@qwikioffice.com
 * 
 * http://www.qwikioffice.com/license
 */

QoDesk.QoPreferences.Shortcuts = Ext.extend(Ext.Panel, {
    constructor: function(config) {
        // constructor pre-processing
        config = config || {};

        this.ownerModule = config.ownerModule;

        // this config
        Ext.applyIf(config, {
            border: false,
            buttons: [{
                disabled: this.ownerModule.app.isAllowedTo('saveShortcut', this.ownerModule.id) ? false: true,
                handler: onSave,
                scope: this,
                text: this.ownerModule.locale.button.save.text
            },
            {
                handler: onClose,
                scope: this,
                text: this.ownerModule.locale.button.close.text
            }],
            cls: 'pref-card',
            items: [{
                bodyStyle: 'padding:0 5px 0 0',
                border: false,
                html: 'Selected applications will be available as a desktop Shortcut.  Don\'t forget to click the \'Save\' button.',
                region: 'center',
                xtype: 'panel'
            },
            new QoDesk.QoPreferences.CheckTree({
                launcherKey: 'shortcut',
                listeners: {
                    'checkchange': {
                        fn: onCheckChange,
                        scope: this
                    }
                },
                ownerModule: config.ownerModule,
                region: 'west'
            })],
            layout: 'border',
            title: this.ownerModule.locale.title.shortcuts
        });

        QoDesk.QoPreferences.Shortcuts.superclass.constructor.apply(this, [config]);
        // constructor post-processing
        function onClose() {
            this.ownerModule.win.close();
        }

        function onSave() {
            this.buttons[0].disable();
            this.ownerModule.save({
                method: 'saveShortcut',
                callback: function() {
                    this.buttons[0].enable();
                },
                callbackScope: this,
                ids: Ext.encode(this.ownerModule.app.getDesktop().getLauncher('shortcut'))
            });
        }
        function onCheckChange(node, checked) {
            if (node.leaf && node.id) {
                if (checked) {
                    this.ownerModule.app.getDesktop().addShortcut(node.id, true);
                } else {
                    this.ownerModule.app.getDesktop().removeShortcut(node.id, true);
                }
            }
        }
    }
});
QoDesk.QoPreferences.Locale = {
    "launcher": {
        "text": "QO Preferences",
        "tooltip": "<b>QO Preferences</b><br />Allows you to modify your desktop"
    },
    "button": {
        "back": {
            "text": "Back"
        },
        "backgroundColor": {
            "text": "Background Color"
        },
        "close": {
            "text": "Close"
        },
        "fontColor": {
            "text": "Font Color"
        }

        ,
        "next": {
            "text": "Next"
        },
        "save": {
            "text": "Save"
        }
    },
    "connection": {
        "lost": {
            "msg": "Lost connection to server.",
            "title": "Error"
        }
    },
    "error": {
        "msg": "Errors encountered on the server.",
        "title": "Error"
    },
    "data": {
        "nav": [{
            "cls": "icon-pref-shortcut",
            "id": "viewShortcuts",
            "text": "Shortcuts",
            "description": "Choose which applications appear in your shortcuts"
        },
        {
            "cls": "icon-pref-autorun",
            "id": "viewAutoRun",
            "text": "Auto Run",
            "description": "Choose which applications open automatically once logged in"
        },
        {
            "cls": "icon-pref-quickstart",
            "id": "viewQuickstart",
            "text": "Quick Start",
            "description": "Choose which applications appear in your Quick Start panel"
        },
        {
            "cls": "icon-pref-appearance",
            "id": "viewAppearance",
            "text": "Window Color and Appearance",
            "description": "Fine tune window color and style of your windows"
        },
        {
            "cls": "icon-pref-wallpaper",
            "id": "viewWallpapers",
            "text": "Desktop Background",
            "description": "Choose from available wallpapers or colors to decorate you desktop"
        }]
    },
    "html": {
        "autorun": "Selected applications will load and run automatically when you sign in.  Don\"t forget to click the \"Save\" button.<br /><br /><b>Note:</b><br />The more applications selected, the longer startup will take.",
        "quickstart": "Selected applications will be available from the Quick Start panel.  Don\"t forget to click the \"Save\" button."
    },
    "label": {
        "backgroundColor": "Choose a background color",
        "fontColor": "Choose a font color",
        "transparency": "Taskbar Transparency",
        "wallpaperPosition": "How should the wallpaper be positioned?"
    },
    "notification": {
        "saved": {
            "msg": "Save complete.",
            "title": "Finished"
        },
        "saving": {
            "msg": "Saving your data...",
            "title": "Please wait"
        }
    },
    "title": {
        "appearance": "Window Color And Appearance",
        "autorun": "Auto Run",
        "background": "Desktop Background",
        "quickstart": "Quick Start",
        "shortcuts": "Shortcuts",
        "window": "QO Preferences"
    }
};